// 使用泛型来定义函数
function log<T>(value: T): T {
  console.log(value)
  return value
}
log<string[]>(['a', 'b'])
log(['a', 'b'])

// type Log = <T>(value: T) => T
// let myLog: Log = log

interface Log {
  <T>(value: T): T
}

let myLog = log
myLog('1')

class Log1<T>{
  run(value: T) {
    console.log(value)
    return value
  }
}
let log1 = new Log1<number>()
log1.run(1)
let log2 = new Log1()
log2.run({ a: 1 })
log2.run('1')


//泛型的约束
interface Length {
  length: number
}
function log3<T extends Length>(value: T): T {
  console.log(value, value.length)
  return value
}
log3([1])
log3('123')
log3({ length: 1 })

// 泛型的好处
/***1，函数和类可以很轻松的支持多种类型，增强程序的扩展性
 *  2，不必写多条函数重载，冗长的联合类型声明，增强代码可读性
 * ·3，灵活控制类型之间的约束
 */